use std::sync::{mpsc, Arc, Mutex};
use std::thread::{self, JoinHandle};
use std::time::Duration;

// fn thread_println() {
//     thread::spawn(|| {
//         for i in 1..10  {
//             println!("hi number {i} from the spawned thread!");
//             thread::sleep(Duration::from_millis(1));
//         }
//     });

//     for i in 1..5  {
//         println!("hi number {i} from the main thread!");
//         thread::sleep(Duration::from_millis(1));
//     }
// }

// fn thread_join() {
//     let join_handle = thread::spawn(|| {
//         for i in 1..10  {
//             println!("hi number {i} from the spawned thread!");
//             thread::sleep(Duration::from_millis(1));
//         }
//     });

//     join_handle.join().unwrap();

//     for i in 1..5  {
//         println!("hi number {i} from the main thread!");
//         thread::sleep(Duration::from_millis(1));
//     }
//     //join_handle.join().unwrap();
// }


// fn thread_move() {
//     let v = vec![1,2,3];
//     // let handle = thread::spawn(||{
//     //     println!("Here's a vector: {v:?}");
//     // });
//     let handle = thread::spawn(move||{
//         println!("Here's a vector: {v:?}");
//     });
//     //drop(v);
//     handle.join().unwrap();
// }

// fn thread_channel(){
//     let (tx, rx) = mpsc::channel();
//     thread::spawn(move||{
//         let msg = String::from("hi");
//         tx.send(msg).unwrap();
//         //println!("send msg {msg}");
//     });

//     let rec_msg = rx.recv().unwrap();
//     println!("receive msg: {rec_msg}");
// }

// fn thread_channel_sleep(){
//     let (tx, rx) = mpsc::channel();
//     thread::spawn(move||{
//         let vars = vec![
//             String::from("hi"),
//             String::from("msg"),
//             String::from("from"),
//             String::from("the"),
//             String::from("thread"),
//         ];

//         for ms in vars {
//             tx.send(ms).unwrap();
//             thread::sleep(Duration::from_secs(1));
//         }
//     });

//     for rec_msg in rx {
//         println!("receive msg: {rec_msg}");    
//     }
// }

// fn thread_channel_more_sender(){
//     let (tx, rx) = mpsc::channel();
//     let tx1 = tx.clone();

//     thread::spawn(move||{
//         let vars = vec![
//             String::from("hi"),
//             String::from("msg"),
//             String::from("from"),
//             String::from("the"),
//             String::from("thread"),
//         ];

//         for ms in vars {
//             tx.send(ms).unwrap();
//             thread::sleep(Duration::from_secs(1));
//         }
//     });

//     thread::spawn(move||{
//         let vars = vec![
//             String::from("hi_1"),
//             String::from("msg_1"),
//             String::from("from_1"),
//             String::from("the_1"),
//             String::from("thread_1"),
//         ];

//         for ms in vars {
//             tx1.send(ms).unwrap();
//             thread::sleep(Duration::from_secs(1));
//         }
//     });

//     for rec_msg in rx {
//         println!("receive msg: {rec_msg}");    
//     }
// }

// fn thread_share_memory(){
//     let m = Mutex::new(5);
//     {
//         let mut num = m.lock().unwrap();
//         *num = 6;
//     }
//     println!("m = {m:?}");
// }

fn multiple_thread_share_memory(){
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];
    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move||{
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("Result: {}", *counter.lock().unwrap());
}

fn main() {
    //1
    //thread_println();
    // 2
    // thread_join();
    //3
    //thread_move();
    //4
    //thread_channel();
    //5
    //thread_channel_sleep();
    //6
    //thread_channel_more_sender();
    //7
    //thread_share_memory();
    //8
    multiple_thread_share_memory();
}
